﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Xml.Linq;
using System.IO;

namespace A2DFramework.EventService.Configuration
{
    public static class EventServiceConfiguration
    {
        public static void Load()
        {
            string configPath = System.IO.Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "A2D.config");
            if (!File.Exists(configPath))
                throw new Exception("Cannot find eventbus config file.");

            XElement root = XElement.Load(configPath);

            root = root.Element("EventSetting");
            if (root == null)
                throw new Exception("EventSetting node not exists");

            Identifier = GetSelfIdentifier(root);
            RetryConnectInterval = GetRetryConnectInterval(root);
            EventServer = GetEventServerSetting(root.Element("EventServer"));
            EventPairs = GetEventPairsSetting(root.Elements("EventPair"));

            ParseEventsTypes();
        }

        private static void ParseEventsTypes()
        {
            EventMapping = new Dictionary<Type, List<Type>>();

            foreach (var eventPair in EventPairs)
            {
                foreach (var w in eventPair.Whens)
                {
                    Type wType = Type.GetType(w);
                    List<Type> tTypes = new List<Type>();

                    foreach (var t in eventPair.Thens)
                    {
                        Type tType = Type.GetType(t);
                        tTypes.Add(tType);
                    }
                    EventMapping[wType] = tTypes;
                }
            }
        }

        private static List<EventPair> GetEventPairsSetting(IEnumerable<XElement> eventPairs)
        {
            List<EventPair> keypairs = new List<EventPair>();
            foreach(var kp in eventPairs)
            {
                EventPair keypair = new EventPair();
                keypair.Whens = new List<string>();
                keypair.Thens = new List<string>();

                foreach(var w in kp.Element("WhenList").Elements("When"))
                    if(w.Value.Length>0)
                        keypair.Whens.Add(w.Value);

                foreach (var t in kp.Element("ThenList").Elements("Then"))
                    if (t.Value.Length > 0)
                        keypair.Thens.Add(t.Value);

                if (keypair.Whens.Count + keypair.Thens.Count <= 0)
                    continue;

                keypairs.Add(keypair);
            }
            return keypairs;
        }

        private static double GetRetryConnectInterval(XElement root)
        {
            return double.Parse(root.Element("RetryConnectInterval").Value);
        }
        
        private static string GetSelfIdentifier(XElement root)
        {
            return root.Element("Identifier").Value;
        }

        private static EventServer GetEventServerSetting(XElement serverElement)
        {
            EventServer setting = new EventServer();
            setting.Enabled=bool.Parse(serverElement.Element("Enabled").Value);
            setting.Address = serverElement.Element("Address").Value;
            setting.Port = int.Parse(serverElement.Element("Port").Value);
            return setting;
        }

        public static string Identifier { get; set; }
        public static double RetryConnectInterval { get; set; }
        public static EventServer EventServer { get; set; }
        public static List<EventPair> EventPairs { get; set; }

        public static Dictionary<Type, List<Type>> EventMapping { get; set; }
    }

    public class EventServer
    {
        public bool Enabled { get; set; }
        public string Address { get; set; }
        public int Port { get; set; }
    }
    public class EventPair
    {
        public List<string> Whens { get; set; }
        public List<string> Thens { get; set; }
    }
}
